using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using FBroSharp.Lib;
using FBroSharp.Event;
//using FBroSharp.Server;

namespace WebSocket监控器
{
    /// <summary>
    /// 服务器配置类
    /// </summary>
    public class ServerConfiguration
    {
        public string Host { get; set; }
        public int Port { get; set; }
        public int MaxConnections { get; set; }
        public string StaticFileRoot { get; set; }
        public string DefaultFile { get; set; }
        public bool EnableCORS { get; set; }
        public bool EnableWebSocket { get; set; }
    }

    /// <summary>
    /// FBro 服务器事件处理器
    /// </summary>
    public class FBroServerHandler : FBroSharpServerHandle
    {
        private readonly ServerConfiguration _config;
        private readonly Dictionary<int, DateTime> _connections = new Dictionary<int, DateTime>();
        private readonly Action<string> _statusCallback;
        private IFBroSharpServer _server;  // ⚠️ 保存服务器实例

        public FBroServerHandler(ServerConfiguration config, Action<string> statusCallback = null)
        {
            _config = config;
            _statusCallback = statusCallback;
        }

        /// <summary>
        /// 获取服务器实例
        /// </summary>
        public IFBroSharpServer GetServerInstance()
        {
            return _server;
        }

        public override void OnServerCreated(IFBroSharpServer server)
        {
            _server = server;  // ⚠️ 保存服务器实例
            string message = $"✅ 服务器启动: {server.GetAddress()}";
            Console.WriteLine(message);
            _statusCallback?.Invoke(message);
        }

        public override void OnServerDestroyed(IFBroSharpServer server)
        {
            string message = $"🛑 服务器关闭: {server.GetAddress()}";
            Console.WriteLine(message);
            _statusCallback?.Invoke(message);
        }

        public override void OnClientConnected(IFBroSharpServer server, int connection_id)
        {
            _connections[connection_id] = DateTime.Now;
            string message = $"📡 客户端连接: ID={connection_id}, 总连接数={_connections.Count}";
            Console.WriteLine(message);
        }

        public override void OnClientDisconnected(IFBroSharpServer server, int connection_id)
        {
            _connections.Remove(connection_id);
            string message = $"📡 客户端断开: ID={connection_id}, 总连接数={_connections.Count}";
            Console.WriteLine(message);
        }

        public override void OnHttpRequest(IFBroSharpServer server, int connection_id,
            string client_address, IFBroSharpRequest request)
        {
            try
            {
                string url = request.GetURL();
                string method = request.GetMethod();

                Console.WriteLine($"📨 HTTP请求: {method} {url} 来自 {client_address}");

                // 处理静态文件请求
                if (!string.IsNullOrEmpty(_config.StaticFileRoot))
                {
                    ServeStaticFile(server, connection_id, url);
                }
                else
                {
                    // 返回默认响应
                    var html = GenerateDefaultResponse(server);
                    var data = Encoding.UTF8.GetBytes(html);
                    server.SendHttp200Response(connection_id, "text/html", data);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"❌ 处理请求失败: {ex.Message}");
                server.SendHttp500Response(connection_id, $"Internal Server Error: {ex.Message}");
            }
        }

        public override void OnWebSocketConnected(IFBroSharpServer server, int connection_id)
        {
            if (_config.EnableWebSocket)
            {
                string message = $"🔌 WebSocket连接: ID={connection_id}";
                Console.WriteLine(message);
                _statusCallback?.Invoke(message);
            }
        }

        public override void OnWebSocketMessage(IFBroSharpServer server, int connection_id, byte[] data)
        {
            if (_config.EnableWebSocket)
            {
                string content = Encoding.UTF8.GetString(data);
                Console.WriteLine($"💬 WebSocket消息: ID={connection_id}, 长度={data.Length}, 内容={content}");

                // 回显消息（Echo Server）
                server.SendWebSocketMessage(connection_id, data);

                // 也可以发送自定义响应
                // string response = $"服务器收到: {content}";
                // server.SendWebSocketMessage(connection_id, Encoding.UTF8.GetBytes(response));
            }
        }

        private void ServeStaticFile(IFBroSharpServer server, int connection_id, string url)
        {
            // 处理根路径
            if (url == "/" || url == "")
            {
                url = "/" + _config.DefaultFile;
            }

            // 构建文件路径
            var filePath = Path.Combine(_config.StaticFileRoot, url.TrimStart('/'));

            // 安全检查：防止路径遍历
            var fullPath = Path.GetFullPath(filePath);
            var rootPath = Path.GetFullPath(_config.StaticFileRoot);

            if (!fullPath.StartsWith(rootPath))
            {
                server.SendHttp404Response(connection_id);
                return;
            }

            if (File.Exists(fullPath))
            {
                var contentType = GetContentType(Path.GetExtension(fullPath));
                var data = File.ReadAllBytes(fullPath);

                server.SendHttp200Response(connection_id, contentType, data);
                Console.WriteLine($"✅ 发送文件: {Path.GetFileName(fullPath)} ({data.Length} 字节)");
            }
            else
            {
                server.SendHttp404Response(connection_id);
            }
        }

        private string GetContentType(string extension)
        {
            switch (extension.ToLower())
            {
                case ".html": return "text/html; charset=utf-8";
                case ".css": return "text/css";
                case ".js": return "application/javascript";
                case ".json": return "application/json";
                case ".png": return "image/png";
                case ".jpg":
                case ".jpeg": return "image/jpeg";
                case ".gif": return "image/gif";
                case ".svg": return "image/svg+xml";
                case ".ico": return "image/x-icon";
                case ".txt": return "text/plain";
                case ".pdf": return "application/pdf";
                case ".woff": return "font/woff";
                case ".woff2": return "font/woff2";
                case ".ttf": return "font/ttf";
                default: return "application/octet-stream";
            }
        }

        private string GenerateDefaultResponse(IFBroSharpServer server)
        {
            return $@"<!DOCTYPE html>
<html lang='zh-CN'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>FBro Server - WebSocket 测试服务器</title>
    <style>
        * {{ margin: 0; padding: 0; box-sizing: border-box; }}
        body {{ 
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 40px; 
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
        }}
        .container {{ 
            background: white; 
            padding: 40px; 
            border-radius: 12px; 
            box-shadow: 0 10px 40px rgba(0,0,0,0.2);
            max-width: 800px;
            margin: 0 auto;
        }}
        h1 {{ 
            color: #333;
            margin-bottom: 10px;
            font-size: 32px;
        }}
        .subtitle {{
            color: #666;
            margin-bottom: 30px;
            font-size: 16px;
        }}
        .info {{ 
            margin: 20px 0; 
            padding: 20px; 
            background: #f0f8ff; 
            border-left: 4px solid #007cba;
            border-radius: 4px;
        }}
        .info p {{
            margin: 8px 0;
            line-height: 1.6;
        }}
        .info strong {{
            color: #333;
            font-weight: 600;
        }}
        .status {{
            display: inline-block;
            padding: 4px 12px;
            border-radius: 12px;
            font-size: 14px;
            font-weight: 500;
        }}
        .status.active {{
            background: #4caf50;
            color: white;
        }}
        .status.inactive {{
            background: #f44336;
            color: white;
        }}
        .test-section {{
            margin-top: 30px;
            padding: 20px;
            background: #f9f9f9;
            border-radius: 8px;
        }}
        .test-section h2 {{
            color: #333;
            margin-bottom: 15px;
            font-size: 20px;
        }}
        #wsMessages {{
            background: #000;
            color: #0f0;
            padding: 15px;
            border-radius: 4px;
            font-family: 'Consolas', monospace;
            font-size: 13px;
            max-height: 300px;
            overflow-y: auto;
            margin: 15px 0;
        }}
        input[type='text'] {{
            width: calc(100% - 120px);
            padding: 10px;
            border: 2px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }}
        button {{
            padding: 10px 20px;
            margin: 5px;
            border: none;
            border-radius: 4px;
            background: #007cba;
            color: white;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: background 0.3s;
        }}
        button:hover {{
            background: #005a8c;
        }}
        button:disabled {{
            background: #ccc;
            cursor: not-allowed;
        }}
        .footer {{
            margin-top: 30px;
            text-align: center;
            color: #666;
            font-size: 14px;
        }}
    </style>
</head>
<body>
    <div class='container'>
        <h1>🎉 FBro Server</h1>
        <p class='subtitle'>WebSocket 测试服务器运行中</p>
        
        <div class='info'>
            <p><strong>服务器地址:</strong> {server.GetAddress()}</p>
            <p><strong>当前连接数:</strong> {_connections.Count}</p>
            <p><strong>WebSocket:</strong> <span class='status {(_config.EnableWebSocket ? "active" : "inactive")}'>{(_config.EnableWebSocket ? "已启用" : "已禁用")}</span></p>
            <p><strong>CORS:</strong> <span class='status {(_config.EnableCORS ? "active" : "inactive")}'>{(_config.EnableCORS ? "已启用" : "已禁用")}</span></p>
        </div>

        <div class='test-section'>
            <h2>🔌 WebSocket 测试</h2>
            <div>
                <button id='connectBtn' onclick='connect()'>连接 WebSocket</button>
                <button id='disconnectBtn' onclick='disconnect()' disabled>断开连接</button>
            </div>
            <div id='wsMessages'>[等待连接...]</div>
            <div>
                <input type='text' id='messageInput' placeholder='输入消息内容' />
                <button id='sendBtn' onclick='sendMessage()' disabled>发送</button>
            </div>
        </div>

        <div class='footer'>
            <p>Powered by FBro Browser Framework</p>
        </div>
    </div>

    <script>
        let ws = null;
        const messagesDiv = document.getElementById('wsMessages');
        const messageInput = document.getElementById('messageInput');
        const connectBtn = document.getElementById('connectBtn');
        const disconnectBtn = document.getElementById('disconnectBtn');
        const sendBtn = document.getElementById('sendBtn');

        function addMessage(msg, type = 'info') {{
            const time = new Date().toLocaleTimeString();
            const colors = {{
                'info': '#0ff',
                'send': '#ff0',
                'receive': '#0f0',
                'error': '#f00'
            }};
            messagesDiv.innerHTML += `<div style='color: ${{colors[type]}}'>[$${{time}}] $${{msg}}</div>`;
            messagesDiv.scrollTop = messagesDiv.scrollHeight;
        }}

        function connect() {{
            try {{
                const wsUrl = 'ws://{_config.Host}:{_config.Port}';
                addMessage('正在连接到: ' + wsUrl, 'info');
                
                ws = new WebSocket(wsUrl);
                
                ws.onopen = function() {{
                    addMessage('✅ WebSocket 连接成功！', 'info');
                    connectBtn.disabled = true;
                    disconnectBtn.disabled = false;
                    sendBtn.disabled = false;
                }};
                
                ws.onmessage = function(e) {{
                    addMessage('◀ 收到: ' + e.data, 'receive');
                }};
                
                ws.onerror = function(error) {{
                    addMessage('❌ 错误: ' + error, 'error');
                }};
                
                ws.onclose = function() {{
                    addMessage('🔌 连接已关闭', 'info');
                    connectBtn.disabled = false;
                    disconnectBtn.disabled = true;
                    sendBtn.disabled = true;
                }};
            }} catch(e) {{
                addMessage('❌ 连接失败: ' + e.message, 'error');
            }}
        }}

        function disconnect() {{
            if (ws) {{
                ws.close();
                ws = null;
            }}
        }}

        function sendMessage() {{
            const msg = messageInput.value.trim();
            if (msg && ws && ws.readyState === WebSocket.OPEN) {{
                ws.send(msg);
                addMessage('▶ 发送: ' + msg, 'send');
                messageInput.value = '';
            }}
        }}

        messageInput.addEventListener('keypress', function(e) {{
            if (e.key === 'Enter') {{
                sendMessage();
            }}
        }});
    </script>
</body>
</html>";
        }

        public int GetConnectionCount()
        {
            return _connections.Count;
        }
    }

    /// <summary>
    /// 服务器实例管理器（单例模式）
    /// </summary>
    public class ServerInstanceManager
    {
        private static ServerInstanceManager _instance;
        public static ServerInstanceManager Instance => _instance ?? (_instance = new ServerInstanceManager());

        private readonly Dictionary<string, IFBroSharpServer> _servers = new Dictionary<string, IFBroSharpServer>();
        private readonly Dictionary<string, ServerConfiguration> _configs = new Dictionary<string, ServerConfiguration>();

        private ServerInstanceManager() { }

        public void RegisterServer(string serverId, IFBroSharpServer server, ServerConfiguration config)
        {
            _servers[serverId] = server;
            _configs[serverId] = config;
        }

        public IFBroSharpServer GetServer(string serverId)
        {
            return _servers.TryGetValue(serverId, out var server) ? server : null;
        }

        public ServerConfiguration GetConfig(string serverId)
        {
            return _configs.TryGetValue(serverId, out var config) ? config : null;
        }

        public bool StopServer(string serverId)
        {
            if (_servers.TryGetValue(serverId, out var server))
            {
                server.Dispose();
                _servers.Remove(serverId);
                _configs.Remove(serverId);
                return true;
            }
            return false;
        }

        public void StopAllServers()
        {
            foreach (var server in _servers.Values)
            {
                try
                {
                    server?.Dispose();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"停止服务器时出错: {ex.Message}");
                }
            }
            _servers.Clear();
            _configs.Clear();
        }

        public List<string> GetAllServerIds()
        {
            return new List<string>(_servers.Keys);
        }
    }

    /// <summary>
    /// 服务器操作结果
    /// </summary>
    public class ServerOperationResult
    {
        public bool Success { get; set; }
        public string Message { get; set; }
        public object Data { get; set; }

        public static ServerOperationResult Succeeded(string message, object data = null)
        {
            return new ServerOperationResult
            {
                Success = true,
                Message = message,
                Data = data
            };
        }

        public static ServerOperationResult Failed(string message)
        {
            return new ServerOperationResult
            {
                Success = false,
                Message = message,
                Data = null
            };
        }
    }
}

